import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
import store from '@/store'

// export function getPwdMD5Str (pwd) {
//   let str = CryptoJS.MD5(pwd + CryptoJS.MD5(pwd)).toString()
//   str = str.substring(0, 16)
//   return str
// }

// eslint-disable-next-line sonarjs/cognitive-complexity
export function CRC32 (str, radix = 16) {
  const Utf8Encode = function (string) {
    string = string.replace(/\r\n/g, '\n')
    let text = ''
    for (let n = 0; n < string.length; n++) {
      const c = string.charCodeAt(n)
      if (c < 128) {
        text += String.fromCharCode(c)
      } else if ((c > 127) && (c < 2048)) {
        text += String.fromCharCode((c >> 6) | 192)
        text += String.fromCharCode((c & 63) | 128)
      } else {
        text += String.fromCharCode((c >> 12) | 224)
        text += String.fromCharCode(((c >> 6) & 63) | 128)
        text += String.fromCharCode((c & 63) | 128)
      }
    }
    return text
  }
  const makeCRCTable = function () {
    let c
    const crcTable = []
    for (let n = 0; n < 256; n++) {
      c = n
      for (let k = 0; k < 8; k++) {
        c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1))
      }
      crcTable[n] = c
    }
    return crcTable
  }
  const crcTable = makeCRCTable()
  const strUTF8 = Utf8Encode(str)
  let crc = 0 ^ (-1)
  for (let i = 0; i < strUTF8.length; i++) {
    crc = (crc >>> 8) ^ crcTable[(crc ^ strUTF8.charCodeAt(i)) & 0xFF]
  }
  crc = (crc ^ (-1)) >>> 0
  return crc.toString(radix).toUpperCase()
}
export function EncryptRSA (word) {
  const encryptor = new JSEncrypt()
  const pubkey = store.state.system.pubkey
  encryptor.setPublicKey(pubkey)
  return encryptor.encrypt(word)
}
export function randomString (e = 16) {
  var t = 'ABCDEFGHJKMNPQRSTWXYZ123456789'
  var a = t.length
  var n = ''
  for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a))
  return n
}
export function Encrypt (word) {
  const key = randomString()
  const formatedKey = CryptoJS.enc.Utf8.parse(key)
  const encryptKey = EncryptRSA(key)
  let srcs, crc, encrypt
  if (word) {
    if (typeof word === 'object') {
      srcs = JSON.stringify(word)
    } else {
      srcs = word
    }
    crc = CRC32(srcs)
    const encrypted = CryptoJS.AES.encrypt(srcs, formatedKey, { iv: formatedKey, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
    encrypt = CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
  }
  return {
    key,
    crc,
    encryptKey,
    encrypt
  }
}
export function Decrypt (word, key) {
  const formatedKey = CryptoJS.enc.Utf8.parse(key)
  const decrypt = CryptoJS.AES.decrypt(word, formatedKey, { iv: formatedKey, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
  let data
  try {
    data = JSON.parse(decryptedStr)
  } catch (e) {
    data = decryptedStr
  }
  return data
}
